// Reciever.h

#ifndef _RECIEVER_h
#define _RECIEVER_h
#include "nRF24L01.h"
#include "RF24.h"
#include "StarburstCommon.h"

#define NOTHING_RECIEVED 0
#define MODE_CHANGE_RECIEVED 1
#define MIRRORED_LEG_DATA_RECIEVED 2
#define DISCONNECTED 3
#define UNEXPECTED_DATA_RECIEVED 4
class Reciever
{
  
public:
  Reciever(uint8_t cePin, uint8_t csPin) : radio(cePin,csPin) {
  }
  void init() {
      initRadio(radio, true);
      currentMode = Loading;
  }
  Mode getCurrentMode() {
    return currentMode;
  }

  void setCurrentMode(Mode mode) {
    currentMode = mode;
  }

  int readMessage(void **result) {
    if(radio.available()) {
      if(radio.read(buffer, radio.getPayloadSize())) {
        // small delay to allow response
        if(isEmpty()) {
          return NOTHING_RECIEVED;
        }
#ifdef PRINT_DEBUG
        for(int i = 0; i < radio.getPayloadSize(); i++ ) {
          Serial.print(buffer[i]);
          Serial.print(" ");
        }
        Serial.println();
#endif
        if(isModeMessage()) {
          
          modeMessage.copyFrom(buffer);
          currentMode = modeMessage.mode;
          if(prevMessage.mode == modeMessage.mode &&
            prevMessage.arg1 == modeMessage.arg1 &&
            prevMessage.arg2 == modeMessage.arg2 &&
            prevMessage.arg3 == modeMessage.arg3)
            return NOTHING_RECIEVED;
          Serial.println(modeMessage.mode);
          memcpy(&prevMessage, &modeMessage,sizeof(ModeMessage));
          *result = &modeMessage;
          return MODE_CHANGE_RECIEVED;
        }
        else if(isDataMessage()) {
          memcpy(&prevMessage,0,sizeof(prevMessage));
          if(memcmp(buffer,audioBreak,4) == 0) {
            *result = NULL;
            return DISCONNECTED;
          }
          if(currentMode != Sound) {
            return UNEXPECTED_DATA_RECIEVED;
          }
          else {
            for(int i = 0; i < MIRRORED_LEGS; i++) { 
              int pos = i/2 + 1;
              int nibble = i % 2;
              legData[i].legNumber = i;
              if(nibble == 0 )
                legData[i].value = buffer[pos] & 0xF;
              else
                legData[i].value = (buffer[pos] >> 4) & 0xF;
            }
            *result = &legData;
            return MIRRORED_LEG_DATA_RECIEVED;
        }        
        }
      }

    }
    result = NULL;
    return NOTHING_RECIEVED;
    
  }

private:
  LegData legData[16];
  ModeMessage modeMessage;
  ModeMessage prevMessage;
  Mode currentMode;
  uint8_t buffer[32];
  RF24 radio;

  bool isModeMessage() {
    return buffer[0] == 1;
  }

  bool isDataMessage() {
    return buffer[0] == 0;
  }

  bool isEmpty() {
    for(int i = 0; i <radio.getPayloadSize(); i++) {
      if(buffer[i] != 0)
        return false;
    }
    return true;
  }
  

};

#endif

